package org.lboot.idmo.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Validator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.lboot.core.domain.ResponseDTO;
import org.lboot.idmo.module.role.SysRole;
import org.lboot.idmo.module.role.SysRoleService;
import org.lboot.idmo.module.role.params.RoleCreateParams;
import org.lboot.idmo.module.role.params.RoleQueryParams;
import org.lboot.idmo.module.role.params.RoleUpdateParams;
import org.lboot.idmo.module.user.SysUser;
import org.lboot.idmo.module.user.role.SysUserRole;
import org.lboot.idmo.module.user.role.SysUserRoleService;
import org.lboot.idmo.util.RbacUtil;
import org.lboot.jpa.utils.JpaDataUtil;
import org.lboot.llog.anno.ApiLog;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("idm")
@AllArgsConstructor
@Api(tags = "角色管理")
public class IdmoRoleController {
    SysRoleService roleService;

    SysUserRoleService userRoleService;
    @ApiLog("角色管理")
    @PostMapping("roles")
    @ApiOperation(value = "角色新建",notes = "")
    public ResponseDTO<Object> roleCreate(@RequestBody @Validated RoleCreateParams params){
        SysRole role = new SysRole();
        BeanUtil.copyProperties(params,role, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        //新建条件核查
        roleService.createCheck(role);
        return ResponseDTO.succData(
                roleService.saveOne(role)
        );
    }

    @ApiLog("角色管理")
    @DeleteMapping("roles/{roleId}")
    @ApiOperation(value = "角色删除",notes = "")
    public ResponseDTO<Object> roleDelete(@PathVariable("roleId") Long roleId){
        // 先清除关联用户信息
        userRoleService.deleteByRoleId(roleId);
        // 清除角色
        roleService.deleteOne(roleId);
        return ResponseDTO.succMsg("删除成功");
    }

    @ApiLog("角色管理")
    @PutMapping("roles")
    @ApiOperation(value = "角色修改",notes = "")
    public ResponseDTO<Object> roleUpdate(@RequestBody @Validated RoleUpdateParams params){
        SysRole role = roleService.getOneUnwrap(params.getId());
        BeanUtil.copyProperties(params,role,CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
        // 核查
        roleService.updateCheck(role);
        return ResponseDTO.succData(
                roleService.updateOne(role)
        );
    }


    @ApiLog("角色管理")
    @PutMapping("roles/{roleId}")
    @ApiOperation(value = "角色修改",notes = "")
    public ResponseDTO<Object> roleUpdate(@PathVariable("roleId") Long roleId,@RequestBody @Validated RoleUpdateParams params){
        SysRole role = roleService.getOneUnwrap(roleId);
        BeanUtil.copyProperties(params,role,CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
        // 核查
        roleService.updateCheck(role);
        return ResponseDTO.succData(
                roleService.updateOne(role)
        );
    }


    @GetMapping("roles/{roleId}")
    @ApiOperation(value = "角色查询",notes = "")
    public ResponseDTO<Object> roleQuery(@PathVariable("roleId") Long roleId){
        return ResponseDTO.succData(
                roleService.getOne(roleId)
        );
    }

    @GetMapping("roles/{roleId}/users")
    @ApiOperation(value = "角色关联用户查询",notes = "")
    public ResponseDTO<Object> roleUsersQuery(@PathVariable("roleId") Long roleId){
        List<SysUser> users = userRoleService.getUsers(roleId);
        // 数据脱敏
        users = users.stream().map(RbacUtil::desensitize).collect(Collectors.toList());
        return ResponseDTO.succData(users);
    }

    @Data
    private class RoleOption{
        String id;
        String name;
        String key;
    }
    @GetMapping("roles/options")
    @ApiOperation(value = "全部角色(选项)")
    public ResponseDTO<Object> allRoleOptions(){
        List<SysRole> roles = roleService.getAll();
        List<RoleOption> options = new ArrayList<>();
        for (SysRole role:roles){
            RoleOption option = new RoleOption();
            option.setKey(role.getRoleKey());
            option.setName(role.getRoleName());
            option.setId(role.getRoleKey());
            options.add(option);
        }
        return ResponseDTO.succData(options);
    }

    @GetMapping("roles")
    @ApiOperation(value = "角色列表",notes = "")
    public ResponseDTO<Object> roleListQuery(RoleQueryParams params){

        // tips : 页码对应 - 1
        Pageable pageable = JpaDataUtil.buildPageable(params);
        // 如果参数为空
        Specification<SysRole> spec = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            // 构建 pr 模糊 查询
            if (Validator.isNotEmpty(params.getSearchKey())){
                Predicate p1 = cb.like(root.get("roleName"),   "%"+params.getSearchKey() + "%");
                Predicate p2 = cb.like(root.get("roleKey"),  "%"+ params.getSearchKey() + "%");
                list.add(cb.or(p1,p2));
            }
            // 基于状态查询
            if (Validator.isNotEmpty(params.getStatus())){
                Predicate p1 = cb.equal(root.get("status"),params.getStatus());
                list.add(p1);
            }
            // 如果部门信息不为空
            if (Validator.isNotEmpty(params.getUnitId())){
                Predicate p2 = cb.equal(root.get("unitId"),params.getUnitId());
                list.add(p2);
            }
            Predicate[] predicates = new Predicate[list.size()];
            return cb.and(list.toArray(predicates));
        };
        return ResponseDTO.succData(
                roleService.getAll(pageable,spec)
        );
    }

    @Data
    @ApiModel(value = "角色授权参数")
    public static class RoleGrantParams {
        private List<Long> userIds;
    }


    @PostMapping("roles/{roleId}/grant")
    @ApiOperation(value = "角色授权")
    public ResponseDTO<Object> roleGrant(@PathVariable("roleId") Long roleId, @Validated @RequestBody RoleGrantParams params){
        List<SysUserRole> userRoles = new ArrayList<>();
        List<Long> userIds = params.getUserIds();
        for (Long userId:userIds){
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRoles.add(userRole);
        }
        userRoleService.batchSave(userRoles);
        return ResponseDTO.succMsg("授权成功");
    }


    @PostMapping("roles/{roleId}/cancel")
    @ApiOperation(value = "角色授权")
    public ResponseDTO<Object> roleCancel(@PathVariable("roleId") Long roleId, @Validated @RequestBody RoleGrantParams params){
        List<Long> userIds = params.getUserIds();
        List<SysUserRole> userRoles = userRoleService.getByRoleId(roleId);
        List<Long> deleteIds = new ArrayList<>();
        for (SysUserRole userRole:userRoles){
            if (userIds.contains(userRole.getUserId())){
                deleteIds.add(userRole.getId());
            }
        }
        userRoleService.batchDelete(deleteIds);
        return ResponseDTO.succMsg("取消授权成功");
    }
}
